#include <sdfs/protobuf/Codec.h>
#include <sdfs/protobuf/heartbeat.pb.h>

#include <muduo/net/Buffer.h>

#include <stdio.h>

using namespace sdfs;

void onHeartBeat(const muduo::net::TcpConnectionPtr& conn,
	const shared_ptr<protobuf::HeartBeat>& msg, muduo::Timestamp time)
{

}

void print(muduo::net::Buffer& buf)
{
	printf("encoded to %zd bytes\n", buf.readableBytes());
	for(size_t i = 0; i < buf.readableBytes() ; ++i)
	{
		unsigned char ch = static_cast<unsigned char>(buf.peek()[i]);
		printf("%2zd:  0x%02x  %c\n", i, ch, isgraph(ch) ? ch : ' ');
	}
}

int32_t asInt32_2(const char* buf)
{
	int32_t be32 = 0;
	::memcpy(&be32, buf, sizeof(int32_t));
	return be32;
}

void outputChar(char* p, size_t size)
{
	for(size_t i = 0 ; i < size ; ++i)
	{
		char ch = *p;
		printf("%2zd:  0x%02x  %c\n", i, ch, isgraph(ch) ? ch : ' ');
		p++;
	}
}

int main()
{
/*
	muduo::net::Buffer buffer;
	int host = -1151792502;
	buffer.appendInt32(host);
	host = asInt32_2(buffer.peek());
	host = 0;

	int host = -1151792502;
	int net = -1979033157;
	char *ph = reinterpret_cast<char *>(&host);
	char *pn = reinterpret_cast<char *>(&net);
	outputChar(ph, 4);
	printf("=============\n");
	outputChar(pn, 4);

	int8_t a[4];
	a[0] = 0x8A;
	a[1] = 0x0A;
	a[2] = 0x59;
	a[3] = 0xBB;
	int o = -1151792502;
//	char *p = reinterpret_cast<char *>(&i);
	int *pi = reinterpret_cast<int *>(a);
	char *pc = reinterpret_cast<char *>(a);
	int t = asInt32_2(pc);
	int net = muduo::net::sockets::hostToNetwork32(t);
	int host = muduo::net::sockets::networkToHost32(net);
	assert(o == *pi);
	printf("*p = %d\n", *pi);
	printf("t = %d\n", t);
	printf("net = %d\n", net);
	printf("host = %d\n", host);

	int32_t t = -1151792502;
	int net = muduo::net::sockets::hostToNetwork32(t);
	printf("net: %d\n", net);
	int host = muduo::net::sockets::networkToHost32(net);
	printf("host: %d\n", host);
*/

	muduo::net::Buffer buf;
	protobuf::HeartBeat heartbeat;
	heartbeat.set_id(1);
	heartbeat.set_free(100);
	heartbeat.set_capacity(1000);

	ProtobufCodec::fillEmptyBuffer(&buf, heartbeat);
	print(buf);
	const int32_t len = buf.readInt32();
	
	assert(len == static_cast<int32_t>(buf.readableBytes()));

	ProtobufCodec::ErrorCode errorCode = ProtobufCodec::kNoError;
	MessagePtr message = ProtobufCodec::parse(buf.peek(), len, &errorCode);
	assert(errorCode == ProtobufCodec::kNoError);
	assert(message != NULL);
	message->PrintDebugString();
	assert(message->DebugString() == heartbeat.DebugString());

	boost::shared_ptr<protobuf::HeartBeat> newHeartBeat=
		boost::static_pointer_cast<protobuf::HeartBeat>(message);
	assert(newHeartBeat != NULL);

}
